/*
 * @Description:
 * @Author: chenjiaxin
 * @Date: 2022-06-19 18:17:12
 * @LastEditTime: 2022-06-19 18:39:00
 * @FilePath: \leetcode\5_集合\01_集合的封装.js
 */
function Set() {
  // 属性
  this.items = {};

  // 方法
  Set.prototype.add = function (value) {
    // 1. 判断是否有这个属性
    if (this.has(value)) {
      return false;
    }

    this.items[value] = value;
    return true;
  };

  // has
  Set.prototype.has = function (value) {
    return this.items.hasOwnProperty(value);
  };

  // remove
  Set.prototype.remove = function (value) {
    // 1. 判断是否有这个值
    if (!this.has(value)) {
      return false;
    }

    delete this.items[value];
    return true;
  };

  //clear
  Set.prototype.clear = function () {
    this.items = {};
  };

  //size
  Set.prototype.size = function () {
    return Object.keys(this.items).length;
  };

  //获取集合中所有的值
  Set.prototype.values = function () {
    return Object.keys(this.items);
  };

  // 集合之间侧操作
  // 并集
  Set.prototype.union = function (otherSet) {
    // 这里的 this -> A
    // otherSet -> B  要求 A B的并集

    // 1. 先创建一个新的集合
    const newSet = new Set();

    // 2. 获取 A 集合中的所有元素,并添加到新集合中
    let values = this.values();
    for (let i = 0; i < values.length; i++) {
      newSet.add(values[i]);
    }

    // 3. 将B集合中的元素添加到 新集合中(不能重复了)
    values = otherSet.values();
    for (let i = 0; i < values.length; i++) {
      // 可以直接添加  因为 add 函数中已经做了判断 重复的不会添加进去
      newSet.add(values[i]);
    }

    return newSet;
  };

  // 交集
  Set.prototype.intersection = function (otherSet) {
    const newSet = new Set();

    const values = this.values();

    for (let i = 0; i < values.length; i++) {
      const item = values[i];
      // 判断 A 集合中的元素 在 B 集合中是否也存在
      if (otherSet.has(item)) {
        newSet.add(item);
      }
    }
    return newSet;
  };

  // 差集
  Set.prototype.difference = function (otherSet) {
    const newSet = new Set();
    const values = this.values();

    for (let i = 0; i < values.length; i++) {
      const item = values[i];
      // 判断 A 集合中的元素 在 B 集合中是否也存在
      if (!otherSet.has(item)) {
        newSet.add(item);
      }
    }
    return newSet;
  };

  // 子集 判断 A 是不是 B的子集
  Set.prototype.subset = function (otherSet) {
    // 这里的 this -> A
    // otherSet -> B
    // 需要 A中的元素 全部包含在 B中才算 A是B的子集
    const values = this.values();

    for (let i = 0; i < values.length; i++) {
      const item = values[i];
      // 判断 A 集合中的元素 在 B 集合中是否存在
      if (!otherSet.has(item)) {
        return false;
      }
    }
    return true;
  };
}
